/**
 * ClientController.h
 *
 *  Created on: 2009-04-17
 *      Author: Jacek Suchowski
 *
 * Klasa odpowieadająca za komunikację z klientem w osobnym wątku
 */

#include "structures.h"
#include "ServerThread.h"
#include "MacCollector.h"

#ifndef CLIENTCONTROLLER_H_
#define CLIENTCONTROLLER_H_

namespace tftp_server
{

/**
 * @class ClientController
 * Klasa w której działa pojedyńczy wątek tworzony dla każdego klienta
 */
class ClientController
{
	/**
	 * Informację o wątku.
	 */
	int threadHandle;
	/**
	 * Numer przypisany do konkretnego wątku.
	 */
	pthread_t threadId;

	/**
	 * Nazwa właśnie ściąganego pliku
	 */
	char fileName[256];
	/**
	 * Numer następnego oczekiwanego bloku w potwierdzeniu
	 */
	int nextBlockNumber;
	/**
	 * wielkość danych wysłanych w ostatnim pakiecie
	 */
	int lastSend;
	/**
	 * Odczytane parametry z paczki odebranej od klienta
	 */
	char mode[256];

	/**
	 * Wskaźnik na klasę zbierającą informacje o numerach MAC.
	 * Potrzebne do odpytywania jakim numerem MAC posługuje się dane IP
	 */
	MacCollector *ptr;
	/**
	 * Ostatnia odebrana od klienta paczka
	 */
	Package package;
	/**
	 * Socket na którym działa klient
	 */
	int socket;
	/**
	 * Struktura z danymi potrzebna do wysyłania paczki do klienta
	 */
	struct sockaddr_in newClientName;

public:
	/**
	 * Konstruktor bezargumentowy
	 */
	ClientController();

	/**
	 * Konstruktor uruchamiający clientControllera w osobnym wątku
	 * @param arg - czy uruchamiać nowy wątek
	 * @param socket_ -  socket za pomocą którego będzie realizowana komunikacja z klientem
	 * @param newClientName_ - struktura z informacjami o połączniu
	 * @param firstPackage_ - pierwsza odebrna przez GlobalServer paczka
	 * @param ptr_ - wskaźnik na klasę zbierającą informacje o numerach MAC.
	 */
	ClientController(bool arg, int socket_, struct sockaddr_in newClientName_, Package firstPackage_, MacCollector *ptr_);

	/**
	 * Metoda pomocnicza umożliwiająca uruchowmienie metody run() w osobnym wątku.
	 * @param arg_ - wskaźnik na strukturę z argumentami niebędnymi to późniejszego przekazania do metody run().
	 */
	static void *runFunc(void * arg);

	/**
	 * Metoda wykoywująca się w ramach wątku ClientControllera.
	 * @param socket_ -  socket za pomocą którego będzie realizowana komunikacja z klientem
	 * @param newClientName_ - struktura z informacjami o połączniu
	 * @param firstPackage_ - pierwsza odebrna przez GlobalServer paczka
	 * @param ptr_ - wskaźnik na klasę zbierającą informacje o numerach MAC.
	 */
	void run(int socket_, struct sockaddr_in newClientName, Package firstPackage_, MacCollector *ptr_);

	/*
	 * Destruektor
	 */
	virtual ~ClientController();

	/**
	 * Metoda wysyłająca dane do klienta
	 * @param package_ -  paczka do wysłania klientowi
	 */
	void send(Package package_);

	/**
	 * Metoda zwracająca adres MAC klienta w zależności od tego jakie ma IP
	 * @param ip -  adres ip do którego podłączona jest maszyna, której adres MAC chcemy odczytać
	 */
	MAC findMac(IP ip);

	/**
	 * Metoda kończy działenie wątku
	 */
	void exit(int status);

	/**
	 * Metoda zwracająca nazwe pliku
	 */
	char* getFileName();

	/**
	 * Metoda zwracająca ip
	 */
	string getIp() const;

	/**
	 * Metoda zwracająca nextBlockNumber
	 */
	int getNextBlockNumber() const;

	/**
	 * Ustawiajaca nextBlockNumber
	 * @param nextBlocknumber -  wartość nextBlockNumber
	 */
	void setNextBlockNumber(int nextblocknumber);

	/**
	 * Metoda zwracająca lastSend
	 */
	int getLastSend() const;

	/**
	 * Metoda zwracająca adres MAC klienta w zależności od tego jakie ma IP
	 * @param ip -  adres ip do którego podłączona jest maszyna, której adres MAC chcemy odczytać
	 */
	void setLastSend(int lastsend);

	/**
	 * Metoda zwracająca mode
	 */
	char* getMode();
};

}

#endif /* CLIENTCONTROLLER_H_ */
